#include<bits/stdc++.h>

using namespace std;

#define MM 1920
#define MN 1080
#define CS 15

#ifndef DEBUG
#define NDEBUG
#endif

unsigned int RGB[MN][MM][3]={0};
const unsigned int zeros[3]={0,0,0};
const char default_str[10]="\x1b[0m";

inline void print2cstr(char str[40],unsigned int ac[3]){
    sprintf(str, "\x1b[48;2;%d;%d;%dm",ac[0],ac[1],ac[2]);
}
inline void print_unicode(const char cstr[40]){
    for(int c=0;c<strlen(cstr);++c){
                printf("\\x%02X",cstr[c]);
            }
}
inline bool is_equal(const unsigned int x[3], const unsigned int y[3]){
    for(int i=0;i<3;i++){
        if(x[i] != y[i])
            return false;
    }
    return true;
}



int main(){
    //printf("%02X %02X\n",'\n', ' '); //得换行为\x0A,空格为\x20
    #ifdef DEBUG
    printf("\n");
    #endif
    int m, n, p, q;//宽、高
    char color[CS];
    cin >> m >> n >> p >> q;

    //输入得到矩阵
    for(int i=0;i<n;i++){        
        for(int j=0;j<m;j++){
            memset(color, 0, CS);
            cin >> color;
            switch(strlen(color)){
                case 2:
                    for(int k=3;k>0;--k){
                        color[3*k] = 0;
                        color[3*k-1] = color[1];
                        color[3*k-2] = color[1];                        
                    }
                    break;
                case 4:
                    for(int k=3;k>0;--k){
                        color[3*k] = 0;
                        color[3*k-1] = color[k];
                        color[3*k-2] = color[k];                        
                    }
                    break;
                case 7:
                    for(int k=3;k>0;--k){
                        color[3*k] = 0;
                        color[3*k-1] = color[2*k];
                        color[3*k-2] = color[2*k-1];                        
                    }
                    color[9]=0;

                    break;
            }
            for(int k=0;k<3;k++){
                sscanf(&color[3*k+1],"%x",&RGB[i][j][k]);
            }
        }
    }
    
    //算出来每个位置第i,j处存储平均值
    for(int i=0; i<n/q;i++){
        for(int j=0; j<m/p;j++){
            for(int k=0;k<3;k++){
                int sum=0;
                for(int s=0;s<q;s++){
                    for(int t=0;t<p;t++){
                        sum += RGB[i*q+s][j*p+t][k];
                    }
                }
                RGB[i*q][j*p][k] = sum/(q*p);
            }
        }
    }
     //输出的几条规则
    /*
    1. 开始时白色为背景，黑色为前景；
    2. 如果上一次颜色与这次颜色一样，不用改变背景颜色;
    3. 最后要将终端颜色改回白色为背景，黑色为前景;
    */
   unsigned int last[3]={0,0,0};
   char cstr[40]={0};
   for(int i=0;i<n/q;i++){
       for(int j=0;j<m/p;j++){
           if(!is_equal(last,RGB[i*q][j*p])){
               if(!is_equal(RGB[i*q][j*p],zeros)){
                    print2cstr(cstr,RGB[i*q][j*p]);
                    print_unicode(cstr);   
               }else{
                   print_unicode(default_str);
               }                
                last[0]=RGB[i*q][j*p][0];
                last[1]=RGB[i*q][j*p][1];
                last[2]=RGB[i*q][j*p][2];
            }                      
            printf("\\x%02X",' ');
            #ifdef DEBUG
            printf("    ");
            #endif
       }
        if(!is_equal(last,zeros)){                
            print_unicode(default_str);
            last[0]=0;
            last[1]=0;
            last[2]=0;
        }    
       printf("\\x%02X",'\n');
       #ifdef DEBUG
       printf("\n");
       #endif
   }
    return 0;
}